package mittens.skat;

public class Card implements Comparable<Card> {
	
	/**
	 * Construct a new card with given suit and value
	 * @param suit see constants in this class
	 * @param value [7-14] [7,8,9...,10,Jack,Queen,King,Ace] I think ace is always high.
	 */
	public Card( int suit, int value ){
		if( suit < 9 || suit > 12 ){
			throw new IllegalArgumentException( "Illegal suit: "+suit);
		}
		if( value < 7 || value > 14 ){
			throw new IllegalArgumentException( "Illegal value: "+value);
		}
		
		suit_  = suit;
		value_ = value;
		
		trumpSuit_ = null;
	}
	
	public int getSuit( ){
		return suit_;
	}
	
	public boolean isTrump( ){
		return game_ == Game.REGULAR && (suit_ == trumpSuit_ || value_ == 11 );
	}
	
	/**
	 * Set this, unless you're playing NULL
	 * @param trumpSuit
	 */
	public void setTrumpSuit( int trumpSuit ){
		trumpSuit_ = trumpSuit;
	}
	
	/**
	 * Always need to set this...
	 * @param game
	 */
	public void setGame( int game ){
		if( game != Game.NULL && game != Game.RAMSHT && game != Game.REGULAR ){
			throw new IllegalArgumentException( "Illegal game: "+game);
		}
		game_  = game;
	}
	
	public int getValue( ){
		return value_;
	}
	
	public int getGame( ){
		return game_;
	}
	
	public boolean equals( Object o ){
		if( !(o instanceof Card) ){
			return false;
		}
		Card c = (Card)o;
		return suit_ == c.suit_ && value_ == c.value_ && game_ == c.game_ && trumpSuit_ == c.trumpSuit_;
	}
	
	public String toString( ){
		// UGggh... 
		return valueToString() +" of "+ suitToString() + (isTrump() ? " !TRUMP!":"");
	}
	
	private String suitToString( ){
		switch(suit_){
		case SPADES:
			return "Spades";
		case HEARTS:
			return "Hearts";
		case CLUBS:
			return "Clubs";
		case DIAMONDS:
			return "Diamonds";
		}
		return "AAhh!! WTF!";
	}
	
	private String valueToString( ){
		if( value_ == 14 ){
			return "Ace";
		}
		else if( value_ == 11 ){
			return "Jack";
		}
		else if( value_ == 12 ){
			return "Queen";
		}
		else if( value_ == 13 ){
			return "King";
		}
		else{
			return String.valueOf(value_);
		}
	}
	
	/**
	 * If,
	 *   1  : this card beats otherCard
	 *   -1 : otherCard beats this car
	 *   0  : these cards are equal (the winner is determined by who led)
	 *   
	 *   TODO fix jack logic... UGGG doesn't work when diamonds are trump for some reason....
	 */
	public int compareTo(Card otherCard) {
		if( game_ == null ){
			throw new IllegalArgumentException( "Cannot play if you haven't set the game type!!!");
		}
		
		switch( game_ ){
		case Game.NULL:
			return value_.compareTo(otherCard.value_);
		case Game.REGULAR:
			// TODO 10s are HIGH
			if( trumpSuit_ == null ){
				throw new IllegalArgumentException( "Cannot play REGULAR with out a trump suit!!");
			}
			if( isTrump() ){
				if( !otherCard.isTrump() ){
					return 1;
				}
				else { // both are trump
					if( value_ == 11 ){ // this is a jack
						if( otherCard.value_ != 11 ){
							return 1;
						}
						else {
							return suit_.compareTo(otherCard.suit_);
						}
					}
					else {
						return value_.compareTo(otherCard.value_);
					}
				}
			}
			else {
				if( otherCard.isTrump() ){
					return -1;
				}
				else {
					//neither is trump
					return value_.compareTo(otherCard.value_);
				}
			}
			
		case Game.RAMSHT:
			// TODO remember the rules...
			break;
		
		default:
			throw new IllegalArgumentException("Unknown game: "+game_);
		}
		
		return 0;
	}
	
	private Integer suit_;
	private Integer value_;
	private Integer game_ = Game.REGULAR; // nice default
	private Integer trumpSuit_;
	
	
	public static final int    CLUBS = 12;
	public static final int   SPADES = 11;
	public static final int   HEARTS = 10;
	public static final int DIAMONDS = 9;
	
}
